#include <map>	
#include <set>
#include <utility>
#include "Vertex.h"
#include "RankSet.h"
#include "Group.h"
#include "TempVertexContainer.h"
#include "Helpers.h"
#include <cstdlib>

using namespace std;	

//---------------------------------------------------------------------------------
// Public
//---------------------------------------------------------------------------------

//---------------------------------------------------------------------------------
// Ctor
//---------------------------------------------------------------------------------
TempVertexContainer::TempVertexContainer(Graph *graph): m_RelatedGroup(NULL), m_Graph(graph) {}

//---------------------------------------------------------------------------------
// AddVertex: Adds a vertex to the temp set, marks it is still in the graph
//---------------------------------------------------------------------------------
void TempVertexContainer::InsertNewVertex(VertexBase* vertex)
{ 
	Vertex* currentVertex = dynamic_cast<Vertex*>(vertex);
	m_TempSet.insert(currentVertex); 
	currentVertex->MoveToContainer(this,true);
}

//---------------------------------------------------------------------------------
// Clear: Empties set and NULLs related group
//---------------------------------------------------------------------------------
void TempVertexContainer::Clear() 
{
	m_TempSet.clear(); 
	m_RelatedGroup = NULL;
}

//---------------------------------------------------------------------------------
// Begin: returns an iterator pointing to beginning of temp set
//---------------------------------------------------------------------------------
set<Vertex*>::iterator TempVertexContainer::Begin() 
{ 
	return m_TempSet.begin(); 
}

//---------------------------------------------------------------------------------
// End: returns an iterator pointing past the last element in the temp set
//---------------------------------------------------------------------------------
set<Vertex*>::iterator TempVertexContainer::End() 
{ 
	return m_TempSet.end(); 
}

//---------------------------------------------------------------------------------
// Find: Find a vertex in the temp set
// Paramters:
// Vertex *vertex - vertex to find
//---------------------------------------------------------------------------------
set<Vertex*>::iterator TempVertexContainer::Find(Vertex *vertex)
{
	set<Vertex*>::iterator it;
	for (it = m_TempSet.begin(); it != m_TempSet.end(); it++)
	{
		if ( (*it)->Name() == vertex->Name())
		{
			return it;
		}
	}	
	return m_TempSet.end();
}


//---------------------------------------------------------------------------------
// Erase: Erases the vertex at given place
// Parameters:
// it - iterator to place in set to erase
//---------------------------------------------------------------------------------
void TempVertexContainer::Erase(set<Vertex*>::iterator it)
{
	(*it)->ResetContainer();
	m_TempSet.erase(it);
}

//---------------------------------------------------------------------------------
// GetCurrentGroup: Returns group this set is related to (the ones the vertices are
// illegal for)
//---------------------------------------------------------------------------------
Group* TempVertexContainer::GetCurrentGroup() 
{ 
	return m_RelatedGroup; 
}

//---------------------------------------------------------------------------------
// SetCurrentGroup: Changes current group
//---------------------------------------------------------------------------------
void TempVertexContainer::SetCurrentGroup(Group* group) 
{ 
	m_RelatedGroup = group; 
}

//---------------------------------------------------------------------------------
// Count: Returns vertex count
//---------------------------------------------------------------------------------
int TempVertexContainer::Count()
{
	return m_TempSet.size();
}

//---------------------------------------------------------------------------------
// GetContainingGraph: returns containing graph
//---------------------------------------------------------------------------------
Graph *TempVertexContainer::GetContainingGraph()
{
	return m_Graph;
}

//---------------------------------------------------------------------------------
// RemoveVertex: removes vertex from tempset
//---------------------------------------------------------------------------------
void TempVertexContainer::RemoveVertex(Vertex *vertex)
{
	set<Vertex*>::iterator it;
	for (it = m_TempSet.begin(); it != m_TempSet.end(); it++)
	{
		if ( (*it)->Name() == vertex->Name())
		{
			break;
		}
	}	
	if (it == m_TempSet.end())
	{
		throw new GraphColoringException(vertex->PrintName() + " is not in tempset, cannot remove");
	}
	vertex->ResetContainer();
	m_TempSet.erase(it);
}